package com.zhongpengcheng.blog.config;

import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.zhongpengcheng.blog.properties.CaptchaProperties;
import com.zhongpengcheng.blog.properties.FastJsonProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import static com.alibaba.fastjson.serializer.SerializerFeature.*;
import static com.zhongpengcheng.blog.constant.SnowflakeConstants.*;

/**
 * 基础Bean配置
 * <ol>
 *     <li>OSS配置</li>
 *     <li>验证码（captcha）配置</li>
 *     <li>全局唯一ID配置</li>
 *     <li>FastJson配置</li>
 * </ol>
 *
 * @author zhongpengcheng
 * @date 2021/09/02 14:42
 * @since 1.0.0
 **/
@Slf4j
@Configuration
@EnableConfigurationProperties({FastJsonProperties.class, CaptchaProperties.class})
public class BaseConfiguration {

    private final FastJsonProperties fastJsonProperties;
    private final CaptchaProperties captchaProperties;

    @Autowired
    public BaseConfiguration(FastJsonProperties fastJsonProperties, CaptchaProperties captchaProperties) {
        this.fastJsonProperties = fastJsonProperties;
        this.captchaProperties = captchaProperties;
    }

    /**
     * 验证码内容生成器配置
     */
    @Bean
    public MathGenerator mathGenerator() {
        return new MathGenerator(captchaProperties.getNumberLength());
    }

    /**
     * 验证码id生成
     */
    @Bean
    public Snowflake captchaIdGenerator() {
        return IdUtil.getSnowflake(WORKER_ID, DATA_CENTER_ID_FOR_CAPTCHA);
    }

    /**
     * 用户id生成
     */
    @Bean
    public Snowflake userIdGenerator() {
        return IdUtil.getSnowflake(WORKER_ID, DATA_CENTER_ID_FOR_USER_ID);
    }

    /**
     * 日志id生成
     */
    @Bean
    public Snowflake traceIdGenerator() {
        return IdUtil.getSnowflake(WORKER_ID, DATA_CENTER_ID_FOR_LOG_TRACE_ID);
    }

    /**
     * 默认id生成器
     */
    @Bean
    public Snowflake defaultIdGenerator() {
        return IdUtil.getSnowflake(WORKER_ID, DATA_CENTER_ID_FOR_EVERYTHING);
    }
    /**
     * 默认id生成器
     */
    @Bean
    public Snowflake fileIdGenerator() {
        return IdUtil.getSnowflake(WORKER_ID, DATA_CENTER_ID_FOR_FILE);
    }

    /**
     * 使用fastjson做消息转换器
     */
    @Bean
    @SuppressWarnings("deprecation")
    public FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig config = new FastJsonConfig();
        // 设置日期格式化格式
        config.setDateFormat(fastJsonProperties.getDateFormat());
        // 默认编码
        config.setCharset(StandardCharsets.UTF_8);
        // 格式化特性
        config.setSerializerFeatures(getSerializerFeatures());
        // 消息转换器默认response content-type
        converter.setSupportedMediaTypes(ListUtil.of(MediaType.APPLICATION_JSON_UTF8));
        converter.setFastJsonConfig(config);

        return converter;
    }

    /**
     * 构造fastjson的序列化特性
     * @return 注入的序列化特性
     */
    private SerializerFeature[] getSerializerFeatures() {
        ArrayList<SerializerFeature> features = new ArrayList<>();
        // 输出map中value为null的数据
        features.add(WriteMapNullValue);
        // 输出空list为[]，而不是null
        features.add(WriteNullListAsEmpty);
        // 输出空string为""，而不是null
        features.add(WriteNullStringAsEmpty);
        // 使用toString方法序列化枚举
        features.add(WriteEnumUsingToString);
        // 启用美观格式化（会占用更多空间）
        if (fastJsonProperties.getEnablePrettyFormat()) {
            features.add(PrettyFormat);
        }

        return ArrayUtil.toArray(features, SerializerFeature.class);
    }

    /**
     * Mybatis-Plus 分页配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
